﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace ThisIsTheOnlyChamber
{
    abstract class CollisionSystem
    {
        public enum CollisionResult
        {
            NoEvents,
            ButtonPressed,
            GameWon,
            PlayerDeath
        };

        public static CollisionResult Collide(Player p, IList<Wall> walls, IList<Platform> platforms, IList<Button> buttons, Door door)
        {
            BoundingBox playerBoundingBox = p.BoundingBox();

            if (playerBoundingBox.Min.Y < -500f)
                return CollisionResult.PlayerDeath;

            for (int i = 0; i < platforms.Count; i++)
            {
                BoundingBox b = platforms[i].GetBoundingBox();

                if (b.Intersects(playerBoundingBox))
                {
                    if (platforms[i] is WinPlatform)
                        return CollisionResult.GameWon;

                    Vector3[] bCorners = b.GetCorners();
                    Vector3[] pCorners = playerBoundingBox.GetCorners();

                    bool OverlapAbove = false;
                    //float OverlapBelow = 0.0f;
                    float OverlapNorth = 10000f;
                    float OverlapSouth = 10000f;
                    float OverlapEast = 10000f;
                    float OverlapWest = 10000f;

                    //Checks if hits top of platform
                    if (bCorners[0].Y >= pCorners[3].Y && bCorners[3].Y < pCorners[3].Y)
                    {
                        OverlapAbove = true;
                    }

                    //Checks if hits south side of platform
                    if (bCorners[4].Z < pCorners[0].Z && pCorners[0].Z < bCorners[0].Z &&
                         pCorners[4].Z < bCorners[4].Z)
                    {
                        OverlapSouth = pCorners[0].Z - bCorners[4].Z;
                    }

                    //Checks if hits north side of platform
                    if (bCorners[4].Z < pCorners[4].Z && pCorners[4].Z < bCorners[0].Z &&
                         pCorners[0].Z > bCorners[0].Z)
                    {
                        OverlapNorth = bCorners[0].Z - pCorners[4].Z;
                    }

                    //Checks if hits east side of platform
                    if (bCorners[0].X < pCorners[0].X && pCorners[0].X < bCorners[1].X &&
                        pCorners[1].X > bCorners[1].X)
                    {
                        OverlapEast = bCorners[1].X - pCorners[0].X;
                    }

                    //Checks if hits west side of platform
                    if (bCorners[0].X < pCorners[1].X && pCorners[1].X < bCorners[1].X &&
                        pCorners[0].X < bCorners[0].X)
                    {
                        OverlapWest = pCorners[1].X - bCorners[0].X;
                    }

                    if (OverlapAbove)
                    {
                        p.Y = b.GetCorners()[0].Y;
                        p.verticalVelocity = 0.0f;
                    }
                    else if (OverlapSouth < OverlapNorth && OverlapSouth < OverlapEast && OverlapSouth < OverlapWest)
                    {
                        p.Z -= OverlapSouth;
                    }
                    else if (OverlapNorth < OverlapSouth && OverlapNorth < OverlapEast && OverlapNorth < OverlapWest)
                    {
                        p.Z += OverlapNorth;
                    }
                    else if (OverlapEast < OverlapSouth && OverlapEast < OverlapNorth && OverlapEast < OverlapWest)
                    {
                        p.X += OverlapEast;
                    }
                    else if (OverlapWest < OverlapSouth && OverlapWest < OverlapEast && OverlapWest < OverlapNorth)
                    {
                        p.X -= OverlapWest;
                    }
                }
            }

            for (int i = 0; i < walls.Count; i++)
            {
                BoundingBox b = walls[i].GetBoundingBox();

                if (b.Intersects(playerBoundingBox))
                {
                    Vector3[] bCorners = b.GetCorners();
                    Vector3[] pCorners = playerBoundingBox.GetCorners();


                    float OverlapNorth = 10000f;
                    float OverlapSouth = 10000f;
                    float OverlapEast = 10000f;
                    float OverlapWest = 10000f;


                    //Checks if hits south side of platform
                    if (bCorners[4].Z < pCorners[0].Z && pCorners[0].Z < bCorners[0].Z &&
                         pCorners[4].Z < bCorners[4].Z)
                    {
                        OverlapSouth = pCorners[0].Z - bCorners[4].Z;
                    }

                    //Checks if hits north side of platform
                    if (bCorners[4].Z < pCorners[4].Z && pCorners[4].Z < bCorners[0].Z &&
                         pCorners[0].Z > bCorners[0].Z)
                    {
                        OverlapNorth = bCorners[0].Z - pCorners[4].Z;
                    }

                    //Checks if hits east side of platform
                    if (bCorners[0].X < pCorners[0].X && pCorners[0].X < bCorners[1].X &&
                        pCorners[1].X > bCorners[1].X)
                    {
                        OverlapEast = bCorners[1].X - pCorners[0].X;
                    }

                    //Checks if hits west side of platform
                    if (bCorners[0].X < pCorners[1].X && pCorners[1].X < bCorners[1].X &&
                        pCorners[0].X < bCorners[0].X)
                    {
                        OverlapWest = pCorners[1].X - bCorners[0].X;
                    }

                    else if (OverlapSouth < OverlapNorth && OverlapSouth < OverlapEast && OverlapSouth < OverlapWest)
                    {
                        p.Z -= OverlapSouth;
                    }
                    else if (OverlapNorth < OverlapSouth && OverlapNorth < OverlapEast && OverlapNorth < OverlapWest)
                    {
                        p.Z += OverlapNorth;
                    }
                    else if (OverlapEast < OverlapSouth && OverlapEast < OverlapNorth && OverlapEast < OverlapWest)
                    {
                        p.X += OverlapEast;
                    }
                    else if (OverlapWest < OverlapSouth && OverlapWest < OverlapEast && OverlapWest < OverlapNorth)
                    {
                        p.X -= OverlapWest;
                    }
                }
            }

            if ( door != null ) {
                BoundingBox b = door.GetBoundingBox();

                if (b.Intersects(playerBoundingBox))
                {
                    Vector3[] bCorners = b.GetCorners();
                    Vector3[] pCorners = playerBoundingBox.GetCorners();


                    float OverlapNorth = 10000f;
                    float OverlapSouth = 10000f;
                    float OverlapEast = 10000f;
                    float OverlapWest = 10000f;


                    //Checks if hits south side of platform
                    if (bCorners[4].Z < pCorners[0].Z && pCorners[0].Z < bCorners[0].Z &&
                         pCorners[4].Z < bCorners[4].Z)
                    {
                        OverlapSouth = pCorners[0].Z - bCorners[4].Z;
                    }

                    //Checks if hits north side of platform
                    if (bCorners[4].Z < pCorners[4].Z && pCorners[4].Z < bCorners[0].Z &&
                         pCorners[0].Z > bCorners[0].Z)
                    {
                        OverlapNorth = bCorners[0].Z - pCorners[4].Z;
                    }

                    //Checks if hits east side of platform
                    if (bCorners[0].X < pCorners[0].X && pCorners[0].X < bCorners[1].X &&
                        pCorners[1].X > bCorners[1].X)
                    {
                        OverlapEast = bCorners[1].X - pCorners[0].X;
                    }

                    //Checks if hits west side of platform
                    if (bCorners[0].X < pCorners[1].X && pCorners[1].X < bCorners[1].X &&
                        pCorners[0].X < bCorners[0].X)
                    {
                        OverlapWest = pCorners[1].X - bCorners[0].X;
                    }

                    else if (OverlapSouth < OverlapNorth && OverlapSouth < OverlapEast && OverlapSouth < OverlapWest)
                    {
                        p.Z -= OverlapSouth;
                    }
                    else if (OverlapNorth < OverlapSouth && OverlapNorth < OverlapEast && OverlapNorth < OverlapWest)
                    {
                        p.Z += OverlapNorth;
                    }
                    else if (OverlapEast < OverlapSouth && OverlapEast < OverlapNorth && OverlapEast < OverlapWest)
                    {
                        p.X += OverlapEast;
                    }
                    else if (OverlapWest < OverlapSouth && OverlapWest < OverlapEast && OverlapWest < OverlapNorth)
                    {
                        p.X -= OverlapWest;
                    }
                }
            }


            for (int i = 0; i < buttons.Count; i++)
            {
                BoundingBox b = buttons[i].GetBoundingBox();

                if (b.Intersects(playerBoundingBox))
                {

                    Vector3[] bCorners = b.GetCorners();
                    Vector3[] pCorners = playerBoundingBox.GetCorners();

                    bool OverlapAbove = false;


                    //Checks if hits top of button
                    if (bCorners[0].Y >= pCorners[3].Y && bCorners[3].Y < pCorners[3].Y)
                    {
                        OverlapAbove = true;
                    }


                    if (OverlapAbove)
                    {
                        p.Y = b.GetCorners()[0].Y;
                        p.verticalVelocity = 0.0f;
                        return CollisionResult.ButtonPressed;
                    }

                }
            }
            return CollisionResult.NoEvents;
        }
    }
}
